跳到主要内容

MongoDB 的概念

基础概念题

1. MongoDB 与关系型数据库的对应关系

面试官: 请详细说明 MongoDB 中的数据结构与关系型数据库(如 MySQL)中对应概念的映射关系,并解释为什么 MongoDB 不支持表连接?

答案要点:

  • Database ↔ Database(数据库)
  • Collection ↔ Table(集合对应表)
  • Document ↔ Row(文档对应行)
  • Field ↔ Column(字段对应列)
  • Index ↔ Index(索引)
  • Primary Key: MongoDB 自动将 _id 设置为主键

重要区别:

  • MongoDB 不支持 JOIN 操作,因为它是面向文档的 NoSQL 数据库
  • 文档中的键值对是有序的
  • 同一集合中的文档可以有不同的结构

数据类型与结构题

2. BSON 与 JSON 的区别及优势

面试官: 在 Go 项目中使用 MongoDB 时,你了解 BSON 和 JSON 的区别吗?BSON 相比 JSON 有哪些优势和劣势?

答案要点:

BSON 优势:

  1. 更快的遍历速度: 元素长度存储在头部,无需扫描整个文档
  2. 操作更简易: 指定类型后修改不会影响其他数据位置
  3. 更多数据类型: 支持 Date、BinData 等 JSON 不支持的类型

BSON 劣势:

  • 某些情况下占用空间更大(如数字类型至少占用4字节)

3. ObjectId 的结构和作用

面试官: 请详细解释 MongoDB 中 ObjectId 的内部结构,以及如何在 Go 代码中处理 ObjectId?

Go 代码示例:

import (
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)

// 创建新的 ObjectId
objectId := primitive.NewObjectID()

// 获取时间戳
timestamp := objectId.Timestamp()

// 转换为字符串
idString := objectId.Hex()

// 从字符串解析
parsedId, err := primitive.ObjectIDFromHex(idString)

4. MongoDB 文档键命名规范

面试官: MongoDB 文档的键命名有哪些限制?在 Go 开发中如何避免这些问题?

答案要点:

  • 区分类型和大小写
  • 不能有重复键
  • 不能包含 \0(空字符)
  • .$ 有特殊含义
  • _ 开头的键是保留的

高级概念题

5. Capped Collection 的特性和使用场景

面试官: 什么是 Capped Collection?它适用于什么场景?请用时序图说明其工作原理。

特性:

  • 固定大小,按插入顺序存储
  • 高性能,队列过期特性
  • 文档在磁盘上位置固定
  • 更新后文档大小不能超过原大小

使用场景:

  • 日志记录
  • MongoDB oplog
  • 实时数据流

Go 创建示例:

opts := options.CreateCollection().
SetCapped(true).
SetSizeInBytes(100000)

err := db.CreateCollection(context.TODO(), "logs", opts)

6. MongoDB 系统集合和元数据

面试官: MongoDB 中的系统集合有哪些?它们分别存储什么信息?

实际应用题

7. Go 中处理 MongoDB 时间类型

面试官: 在 Go 项目中,如何正确处理 MongoDB 的时间戳和日期类型?请说明它们的区别。

import (
"go.mongodb.org/mongo-driver/bson/primitive"
"time"
)

type Document struct {
ID primitive.ObjectID `bson:"_id,omitempty"`
CreatedAt time.Time `bson:"created_at"`
UpdatedAt primitive.DateTime `bson:"updated_at"`
Timestamp primitive.Timestamp `bson:"timestamp,omitempty"`
}

// 时间处理示例
doc := Document{
CreatedAt: time.Now(),
UpdatedAt: primitive.NewDateTimeFromTime(time.Now()),
}

区别说明:

  • Date: 距离Unix纪元的毫秒数,有符号,支持1970年前的日期
  • Timestamp: 64位值,前32位是time_t,后32位是操作序数,主要用于MongoDB内部

8. MongoDB 在微服务架构中的应用

面试官: 在 Go 微服务架构中,如何设计 MongoDB 的数据库和集合结构?如何处理数据一致性?

设计原则:

  • 每个微服务拥有独立的数据库
  • 避免跨服务的事务操作
  • 使用事件驱动保证最终一致性
  • 合理设计文档结构,减少查询次数

9. MongoDB 性能优化实践

面试官: 在 Go 项目中使用 MongoDB 时,你会采用哪些性能优化策略?

答案要点:

Go 代码示例:

// 连接池配置
clientOpts := options.Client().
ApplyURI(uri).
SetMaxPoolSize(100).
SetMinPoolSize(10).
SetMaxConnIdleTime(30 * time.Second)

// 投影查询
projection := bson.D{{"name", 1}, {"email", 1}}
opts := options.Find().SetProjection(projection)

// 索引创建
indexModel := mongo.IndexModel{
Keys: bson.D{{"user_id", 1}, {"created_at", -1}},
Options: options.Index().SetBackground(true),
}

10. 数据库选择场景题

面试官: 在什么情况下你会选择 MongoDB 而不是 MySQL?请结合具体的业务场景说明。

MongoDB 适用场景:

  • 文档结构经常变化的应用
  • 需要水平扩展的大数据应用
  • 内容管理和目录服务
  • 实时分析和高速日志记录
  • 地理位置相关应用

这些题目涵盖了从基础概念到实际应用的各个方面,特别关注了 Go 开发中的实际使用场景,符合大厂面试的深度和广度要求。

References